namespace ClassyBlog.ExtensionMethods.Specs.Unit
{
    using System;
    using System.Collections.Generic;

    using Machine.Specifications;

    [Subject(typeof(EnumerableExtensions))]
    public class when_trying_to_iterate_of_a_null_enumerable
    {
        static IEnumerable<string> collection;
        static Exception exception;

        Establish context = () => collection = null;

        Because of = () => exception =
            Catch.Exception(() => collection.Each(s =>
                                                      {
                                                      }));

        It should_throw_exception = () =>
            exception.ShouldBeOfType<ArgumentNullException>();
    }

    [Subject(typeof(EnumerableExtensions))]
    public class when_trying_to_iterate_with_a_null_action
    {
        static IEnumerable<string> collection;
        static Exception exception;

        Establish context = () =>
            collection = new List<string>
                             {
                                 "foo",
                                 "bar",
                                 "baz"
                             };

        Because of = () => exception =
            Catch.Exception(() => collection.Each(null));

        It should_throw_exception = () =>
            exception.ShouldBeOfType<ArgumentNullException>();
    }

    [Subject(typeof(EnumerableExtensions))]
    public class when_iterating_enumerable
    {
        static IEnumerable<string> collection;
        static bool iterated;

        Establish context = () =>
            collection = new List<string>
                             {
                                 "foo",
                                 "bar",
                                 "baz"
                             };

        Because of = () => collection.Each(s =>
                                               {
                                                   iterated = true;
                                               });

        It should_iterate = () => iterated.ShouldBeTrue();
    }

    [Subject(typeof(EnumerableExtensions))]
    public class when_trying_to_iterate_with_index_of_a_null_enumerable
    {
        static IEnumerable<string> collection;
        static Exception exception;

        Establish context = () => collection = null;

        Because of = () => exception =
            Catch.Exception(() => collection.EachWithIndex((s, i) =>
                                                               {
                                                               }));

        It should_throw_exception = () =>
            exception.ShouldBeOfType<ArgumentNullException>();
    }

    [Subject(typeof(EnumerableExtensions))]
    public class when_trying_to_iterate_with_index_with_a_null_action
    {
        static IEnumerable<string> collection;
        static Exception exception;

        Establish context = () =>
            collection = new List<string>
                             {
                                 "foo",
                                 "bar",
                                 "baz"
                             };

        Because of = () => exception =
            Catch.Exception(() => collection.EachWithIndex(null));

        It should_throw_exception = () =>
            exception.ShouldBeOfType<ArgumentNullException>();
    }

    [Subject(typeof(EnumerableExtensions))]
    public class when_iterating_enumerable_with_index
    {
        static IEnumerable<string> collection;
        static int lastIndex;

        Establish context = () =>
            collection = new List<string>
                             {
                                 "foo",
                                 "bar",
                                 "baz"
                             };

        Because of = () =>
            collection.EachWithIndex((s, i) =>
                                         {
                                             lastIndex = i;
                                         });

        It should_iterate = () => lastIndex.ShouldEqual(2);
    }
}